package pers.xiaojun.boot.module.infra.dao.entity;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.springframework.util.Assert;
import pers.xiaojun.boot.common.exception.BusinessException;
import pers.xiaojun.boot.common.util.JsonUtils;
import pers.xiaojun.boot.file.core.client.FileClientConfig;
import pers.xiaojun.boot.file.core.client.s3.S3FileClientConfig;
import pers.xiaojun.boot.file.core.constants.FileStorageConstants;
import pers.xiaojun.boot.file.core.enums.FileStorageEnum;
import pers.xiaojun.boot.mybatis.core.enitiy.BaseEntity;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Optional;

import static pers.xiaojun.boot.module.infra.constants.BusinessCodeConstants.FILE_STORAGE_NOT_EXISTS;

/**
 * 文件配置实体
 *
 * @author xiaojun
 * @since 2025-11-13
 */
@TableName(value = "infra_file_config", autoResultMap = true)
@EqualsAndHashCode(callSuper = true)
@Data
public class FileConfigDO extends BaseEntity {

    /**
     * 配置编号，数据库自增
     */
    private Long id;

    /**
     * 配置名
     */
    private String name;

    /**
     * 存储器
     */
    private Integer storage;

    /**
     * 备注
     */
    private String remark;

    /**
     * 是否为主配置
     * <p>
     * 由于我们可以配置多个文件配置，默认情况下，使用主配置进行文件的上传
     */
    private Boolean master;

    /**
     * 文件客户端配置
     * <p>
     * {@link FileClientConfig} JSON格式
     */
    @TableField(typeHandler = FileClientConfigTypeHandler.class)
    private FileClientConfig config;

    @Log4j2
    public static class FileClientConfigTypeHandler extends AbstractJsonTypeHandler<FileClientConfig> {

        public FileClientConfigTypeHandler(Class<?> type) {
            super(type);
        }

        @Override
        @SneakyThrows
        public FileClientConfig parse(String json) {
            Integer storage = JsonUtils.fromJsonAt(json, FileStorageConstants.STORAGE_PROPERTY, Integer.class);
            if (storage == null) {
                log.error("无法获取数据库中 config 中的存储类型");
                return null;
            }
            FileStorageEnum storageEnum = FileStorageEnum.getByStorage(storage);
            if (storageEnum == null) {
                log.error("存储类型不存在：{}", storage);
                return null;
            }
            return JsonUtils.fromJson(json, storageEnum.getConfigClass());
        }

        @Override
        public String toJson(FileClientConfig obj) {
            return JsonUtils.toJson(obj);
        }
    }

}
